package com.example.cola.infrastructure.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.cola.domain.model.*;
import com.example.cola.domain.repository.UserRepository;
import com.example.cola.infrastructure.repository.mapper.UserMapper;
import com.example.cola.infrastructure.repository.po.UserPO;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户仓储实现
 * 
 * @author 资深开发专家
 * @version 1.0
 */
@Repository
public class UserRepositoryImpl implements UserRepository {
    
    private final UserMapper userMapper;
    
    public UserRepositoryImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
    
    @Override
    public void save(User user) {
        UserPO userPO = convertToPO(user);
        if (user.getId() == null) {
            userMapper.insert(userPO);
            user.setId(UserId.of(userPO.getId()));
        } else {
            userMapper.updateById(userPO);
        }
    }
    
    @Override
    public Optional<User> findById(UserId userId) {
        UserPO userPO = userMapper.selectById(userId.getValue());
        return userPO != null ? Optional.of(convertToDomain(userPO)) : Optional.empty();
    }
    
    @Override
    public Optional<User> findByEmail(Email email) {
        LambdaQueryWrapper<UserPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPO::getEmail, email.getValue());
        UserPO userPO = userMapper.selectOne(queryWrapper);
        return userPO != null ? Optional.of(convertToDomain(userPO)) : Optional.empty();
    }
    
    @Override
    public Optional<User> findByPhoneNumber(PhoneNumber phoneNumber) {
        LambdaQueryWrapper<UserPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPO::getPhoneNumber, phoneNumber.getValue());
        UserPO userPO = userMapper.selectOne(queryWrapper);
        return userPO != null ? Optional.of(convertToDomain(userPO)) : Optional.empty();
    }
    
    @Override
    public boolean existsByEmail(Email email) {
        LambdaQueryWrapper<UserPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPO::getEmail, email.getValue());
        return userMapper.selectCount(queryWrapper) > 0;
    }
    
    @Override
    public boolean existsByPhoneNumber(PhoneNumber phoneNumber) {
        LambdaQueryWrapper<UserPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPO::getPhoneNumber, phoneNumber.getValue());
        return userMapper.selectCount(queryWrapper) > 0;
    }
    
    @Override
    public List<User> findUsers(int page, int size, String keyword) {
        Page<UserPO> pageParam = new Page<>(page + 1, size);
        QueryWrapper<UserPO> queryWrapper = new QueryWrapper<>();
        
        if (keyword != null && !keyword.trim().isEmpty()) {
            queryWrapper.like("name", keyword)
                .or().like("email", keyword)
                .or().like("phone_number", keyword);
        }
        
        queryWrapper.orderByDesc("created_time");
        
        Page<UserPO> result = userMapper.selectPage(pageParam, queryWrapper);
        return result.getRecords().stream()
            .map(this::convertToDomain)
            .collect(Collectors.toList());
    }
    
    @Override
    public long countUsers(String keyword) {
        QueryWrapper<UserPO> queryWrapper = new QueryWrapper<>();
        
        if (keyword != null && !keyword.trim().isEmpty()) {
            queryWrapper.like("name", keyword)
                .or().like("email", keyword)
                .or().like("phone_number", keyword);
        }
        
        return userMapper.selectCount(queryWrapper);
    }
    
    @Override
    public void delete(UserId userId) {
        userMapper.deleteById(userId.getValue());
    }
    
    /**
     * 将领域对象转换为持久化对象
     */
    private UserPO convertToPO(User user) {
        UserPO po = new UserPO();
        if (user.getId() != null) {
            po.setId(user.getId().getValue());
        }
        po.setEmail(user.getEmail().getValue());
        po.setPhoneNumber(user.getPhoneNumber() != null ? user.getPhoneNumber().getValue() : null);
        po.setName(user.getName());
        po.setPassword(user.getPassword());
        po.setStatus(user.getStatus().getCode());
        po.setEmailVerified(user.getEmailVerified());
        po.setPhoneVerified(user.getPhoneVerified());
        po.setLastLoginTime(user.getLastLoginTime());
        po.setLastLoginIp(user.getLastLoginIp());
        po.setCreatedTime(user.getCreatedTime());
        po.setUpdatedTime(user.getUpdatedTime());
        return po;
    }
    
    /**
     * 将持久化对象转换为领域对象
     */
    private User convertToDomain(UserPO po) {
        User user = new User();
        user.setId(UserId.of(po.getId()));
        user.setEmail(Email.of(po.getEmail()));
        user.setPhoneNumber(po.getPhoneNumber() != null ? PhoneNumber.of(po.getPhoneNumber()) : null);
        user.setName(po.getName());
        user.setPassword(po.getPassword());
        user.setStatus(UserStatus.fromCode(po.getStatus()));
        user.setEmailVerified(po.getEmailVerified());
        user.setPhoneVerified(po.getPhoneVerified());
        user.setLastLoginTime(po.getLastLoginTime());
        user.setLastLoginIp(po.getLastLoginIp());
        user.setCreatedTime(po.getCreatedTime());
        user.setUpdatedTime(po.getUpdatedTime());
        return user;
    }
}
